package entity

import (
	. "gitee.com/night-tc/gobige/entity/props"
	"gitee.com/night-tc/gobige/global"
	"gitee.com/night-tc/gobige/logger"
	. "gitee.com/night-tc/gobige/msghandler"
)

type ILoop interface {
	/* 生命周期函数 */

	/*
		在创建对象的时候调用
		eid:实例的唯一ID
		etype:实例对象类型
		dbid:实例持久化的唯一ID，如果没有持久化可以使用eid一样
		realPtr:最外面的实例对象引用
		spacePtr:最外面的实例所在空间的引用
		fly:是否为自由对象，不是自由对象时，需要redis里注册路由
	*/
	OnCreated(etype string, eid, dbid uint64, realPtr IEntity, spacePtr IEntities, fly bool, param ...interface{}) error

	//初始化
	Init() error
	//主循环
	mainLoop()
	//循环调用
	Loop()
	//循环调用中间
	Looping()
	//循环调用结尾
	Looped()

	//销毁
	Destroy()
	//恢复到Loop状态
	ReLoop()

	//发生异常的时候
	OnPanic(err error)
}

///////////////////////////////////////////////////////////////
/* 生命周期函数，子类可重载 */

/*
在创建对象的时候调用
eid:实例的唯一ID
etype:实例对象类型
dbid:实例持久化的唯一ID，如果没有持久化可以使用eid一样,也可以为0
realPtr:最外面的实例对象引用
spacePtr:最外面的实例所在空间的引用
fly:是否为自由对象，不是自由对象时，需要redis里注册路由
*/
func (this *Entity) OnCreated(etype string, eid, dbid uint64, realPtr IEntity, spacePtr IEntities, fly bool, param ...interface{}) error {

	this.EntitySess.OnCreated(fly, realPtr, etype, eid, dbid, spacePtr, param...)
	this.EntityTime.OnCreated(spacePtr.GetNowTime())
	this.EntityRun.OnCreated(realPtr)
	if v, ok := realPtr.(IEntityReal); ok {
		this.realPtr = v
	} else {
		return ErrNtt_Struct_Not_Props.NewErr(nil, realPtr)
	}

	// 如果实现了 IMsgOwner 就注册上去
	if v, ok := realPtr.(IMsgOwner); ok {
		realPtr.RegMsgOwner(v)
	}

	//如果绑定了属性就设置
	if p, ok := this.realPtr.(IDef); ok {
		//默认是设置了保存和同步
		defmd := GetTypeMgr().GetDefByName(this.entityType)
		this.PropsSyncContainer = NewPropsSyncContainer()
		this.InitProp(defmd)
		this.SetSrvType(global.GetCfgInst().GetDefType())
		p.SetPropDirtyMgr(this.PropDirtyMgr)
	}
	return nil
}

// 初始化
func (this *Entity) Init() (err error) {
	/*
		注册如果失败，应该走卸载逻辑
		主要注册失败应该是场景部分的逻辑
		场景注册逻辑修改为SaveType，
		这样大场景与副本就一样了
	*/
	if this.GetIsFailLoad() {
		return nil
	}
	if v, ok := this.realPtr.(IPost); ok {
		this.RegMsgProc(&Entity_Proc{owner: v})
	}

	//初始化完成后进入loop状态
	this.SetEntityState(Entity_State_Loop)
	return this.RegEntity()
}

// 循环调用
func (this *Entity) Loop() {
	this.DoMsg()

}

// 循环调用中
func (this *Entity) Looping() {

}

// 循环调用后
func (this *Entity) Looped() {
	if this.PropsSyncContainer != nil {
		// 打包属性
		this.PackPropsSyncProps()
		// 同步属性
		this.realPtr.SyncDirtyProps()
	}
}

// 销毁
func (this *Entity) Destroy() {
	//用于关协程
	this.SetEntityState(Entity_State_Invalid)
	logger.Debugf(logger.LogKey_Entity, "Destroy:%d", this.entityID)
	if this.thgo != nil {
		this.thgo.Cal()
	}
	this.UnRegEntity()

}

// 恢复到Loop状态
func (e *Entity) ReLoop() {

}

// 发生Panic的时候，做的处理
func (this *Entity) OnPanic(err error) {
	ReturnLLoginNtf(this, err)
	// 如果在处理过程中，还有crash，那就直接return，不做其他处理
	if this.GetEntityState() == Entity_State_Destroy && this.GetEntityState() == Entity_State_Invalid {
		return
	}
	logger.Errorf("the entity OnPanic !")
}

/* 生命周期函数，子类可重载 */
///////////////////////////////////////////////////////////////
